package com.openatc.agent.handler;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonSyntaxException;
import com.openatc.agent.service.MsgPostStrategy;
import com.openatc.agent.utils.ApplicationContextProvider;
import com.openatc.comm.data.MessageData;
import com.openatc.comm.handler.IMsgPostHandler;
import com.openatc.core.model.InnerError;
import com.openatc.core.model.RESTRet;
import com.openatc.core.util.RESTRetUtils;
import com.openatc.model.model.ControlPattern;
import org.springframework.beans.BeansException;
import org.springframework.stereotype.Component;

import java.util.logging.Logger;

import static com.openatc.comm.common.CosntDataDefine.*;
import static com.openatc.core.common.IErrorEnumImplInner.E_101;
import static com.openatc.core.common.IErrorEnumImplInner.E_102;
import static com.openatc.core.common.IErrorEnumImplOuter.E_4001;

/**
 * @Classname MsgPostHandler
 * @Description
 * @Date 2022/3/30 23:17
 * @Created by panleilei
 */
@Component
public class MsgPostHandler implements IMsgPostHandler {
    private static Logger logger = Logger.getLogger(MsgPostHandler.class.toString());

    private Gson gson = new Gson();

    private MsgPostStrategy msgPostStrategy;

    @Override
    public RESTRet process(MessageData request, RESTRet response) {
        // 获取消息类型
        String infotype = request.getInfotype();
        String agentid = request.getAgentid();
        String operation = request.getOperation();

        if (infotype == null) {
            InnerError innerError = RESTRetUtils.innerErrorObj(agentid, E_102,request);
            return RESTRetUtils.errorDetialObj(E_4001, innerError);
        }

        if (operation == null) {
            InnerError innerError = RESTRetUtils.innerErrorObj(agentid, E_101, request);
            return RESTRetUtils.errorDetialObj(E_4001, innerError);
        }

        String beanName = getBeanName(request);

        // 没有相应策略的实现时，获取不到bean，表示不做处理
        try {
            msgPostStrategy = (MsgPostStrategy) ApplicationContextProvider.getBean(beanName);
        } catch (BeansException e) {
            return RESTRetUtils.successObj(null);
        }
        try {
            if (response.isSuccess()) {
                // get-request success
                if (getrequest.equals(request.getOperation())) {
                    return msgPostStrategy.successGetProcess(request, response);
                }
                // set-request sueccess
                else {
                    return msgPostStrategy.successSetProcess(request, response);
                }
            } else {
                // get-request failed
                if (getrequest.equals(request.getOperation())) {
                    return msgPostStrategy.failureGetProcess(request, response);
                }
                // set-request failed
                else {
                    return msgPostStrategy.failureSetProcess(request, response);
                }
            }
        } catch (Exception e) {
            logger.info("Post process Error:" + e.getMessage() + ",request is " + beanName + "--" + request.getOperation() + ",agentid is " + agentid
                        + " response success: " + response.isSuccess());
            return RESTRetUtils.successObj(null); // 策略实现类处理出现异常时应答空
        }


    }

    private String getBeanName(MessageData requestData) {
        // 下发改变控制方式指令，需做特殊处理
        if (setrequest.equals(requestData.getOperation()) && ControlPattern.equals(requestData.getInfotype())) {

            JsonElement data = requestData.getData();

            ControlPattern controlPattern = null;
            try {
                controlPattern = gson.fromJson(data, ControlPattern.class);
            } catch (JsonSyntaxException e) {
                logger.warning("Json parse failed!");
                return "";
            }

            if (controlPattern == null) {
                return "";
            }

            return requestData.getInfotype() + "-" + controlPattern.getControl();
        }

        return requestData.getInfotype();
    }

}

















